/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package common;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.*;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageInputStream;
import sun.misc.BASE64Decoder;

/**
 *
 * @author datateknik
 */
public class ImageOpeations {
 
    /**
     * Creates a bufferd image with the correct size,
     * sends it to saveImageToDisk for saving
     * 
     * @param image the image object that is going to be saved to disk
     * @param savePath where the image shuld be saved
     * @return File the newly created file
     * 
     * @throws FileNotFoundException
     * @throws IOException 
     */
    public File saveImage(Image image, String savePath) throws FileNotFoundException, IOException {
        String filename = RandomFilename.createFilename("jpg", savePath);       //create a unique filename
        BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bufferedImage.createGraphics();
        g2.drawImage(image, null, null);
        
        return saveImageToDisk(bufferedImage, savePath, filename);
    }
    
    
    /**
     * Create a thumbnail of an image
     * sends it to saveImageToDisk for saving
     * 
     * @param savePath where the thumbnail is going to be saved
     * @param filename what filename the thumb shuld have
     * 
     * @throws IOException 
     */
    public void saveThumbnail(String savePath, String filename) throws IOException {
        Image image = ImageIO.read(new File(savePath+filename));
        BufferedImage bufferedImage = this.scale((BufferedImage) image);
        
        saveImageToDisk(bufferedImage, savePath+"thumbs/", filename);
    }
    
    
    /**
     * Method to save image to disk
     * 
     * @param image
     * @param width
     * @param height
     * @param savePath
     * @throws FileNotFoundException
     * @throws IOException 
     */
    private File saveImageToDisk(BufferedImage bufferedImage, String savePath, String filename) throws FileNotFoundException, IOException {

        Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
        ImageWriter writer = (ImageWriter)iter.next();
        ImageWriteParam iwp = writer.getDefaultWriteParam();
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality((float)0.8);   //1= maximum quality

        File imageFile = new File(savePath+filename);
        FileImageOutputStream output = new FileImageOutputStream(imageFile);
        writer.setOutput(output);
        IIOImage image2 = new IIOImage(bufferedImage, null, null);
        writer.write(null, image2, iwp);
        writer.dispose();

        return imageFile;
    }
    
    /**
     * Decode a base64 encoded string to an image
     * 
     * @param encoded_data
     * @param extentsion
     * @return
     * @throws IOException 
     */
    public Image base64ToImage(String encoded_data, String extentsion) throws IOException {

        BASE64Decoder decoder = new BASE64Decoder();
        byte[] decodedBytes = decoder.decodeBuffer(encoded_data);                       //Decode base64 image back to image

        ByteArrayInputStream bis = new ByteArrayInputStream(decodedBytes);
        Iterator<?> readers = ImageIO.getImageReadersByFormatName(extentsion);   // read image

        ImageReader reader = (ImageReader) readers.next();
        Object source = bis;
        ImageInputStream iis = ImageIO.createImageInputStream(source);

        reader.setInput(iis, true);
        ImageReadParam param = reader.getDefaultReadParam();
        Image image = reader.read(0, param);

        BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bufferedImage.createGraphics();
        g2.drawImage(image, null, null);
        return image;
    }
    
    
    /**
     * crates a scaled bufferdimage
     * 
     * @param source
     * @return BufferedImage
     */
    private BufferedImage scale(BufferedImage source) {
        int w = (int) (source.getWidth() * 150 / source.getHeight());
        int h = 150;
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = bi.createGraphics();
        double xScale = (double) w / source.getWidth();
        double yScale = (double) h / source.getHeight();
        AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
        g2d.drawRenderedImage(source, at);
        g2d.dispose();
        return bi;
    }
}
